View Javadoc
1   package org.apache.maven.surefire.junitcore;
2   
3   /*
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   *     http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing,
15   * software distributed under the License is distributed on an
16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17   * KIND, either express or implied.  See the License for the
18   * specific language governing permissions and limitations
19   * under the License.
20   */
21  
22  import org.apache.maven.surefire.common.junit4.JUnit4RunListener;
23  import org.apache.maven.surefire.report.ConsoleOutputReceiver;
24  import org.apache.maven.surefire.report.RunListener;
25  import org.apache.maven.surefire.report.SimpleReportEntry;
26  import org.apache.maven.surefire.testset.TestSetFailedException;
27  import org.junit.runner.Description;
28  import org.junit.runner.Result;
29  import org.junit.runner.notification.Failure;
30  
31  /**
32   * A class to be used when there is no JUnit parallelism (methods or/and class). This allow to workaround JUnit
33   * limitation a la Junit4 provider. Specifically, we can redirect properly the output even if we don't have class
34   * demarcation in JUnit. It works when if there is a JVM instance per test run, i.e. with forkMode=always or perthread.
35   */
36  public class NonConcurrentRunListener
37      extends JUnit4RunListener
38      implements ConsoleOutputReceiver
39  {
40  
41      private Description currentTestSetDescription;
42  
43      private Description lastFinishedDescription;
44  
45      public NonConcurrentRunListener( RunListener reporter )
46          throws TestSetFailedException
47      {
48          super( reporter );
49      }
50  
51      public synchronized void writeTestOutput( byte[] buf, int off, int len, boolean stdout )
52      {
53          // We can write immediately: no parallelism and a single class.
54          ( (ConsoleOutputReceiver) reporter ).writeTestOutput( buf, off, len, stdout );
55      }
56  
57      protected SimpleReportEntry createReportEntry( Description description )
58      {
59          return new SimpleReportEntry( description.getClassName(), description.getDisplayName() );
60      }
61  
62      protected SimpleReportEntry createReportEntryForTestSet( Description description )
63      {
64          return new SimpleReportEntry( description.getClassName(), description.getClassName() );
65      }
66  
67      @Override
68      public void testStarted( Description description )
69          throws Exception
70      {
71          finishLastTestSetIfNecessary( description );
72          super.testStarted( description );
73      }
74  
75      private void finishLastTestSetIfNecessary( Description description )
76      {
77          if ( describesNewTestSet( description ) )
78          {
79              currentTestSetDescription = description;
80              if ( lastFinishedDescription != null )
81              {
82                  reporter.testSetCompleted( createReportEntryForTestSet( lastFinishedDescription ) );
83                  lastFinishedDescription = null;
84              }
85              reporter.testSetStarting( createReportEntryForTestSet( description ) );
86          }
87      }
88  
89      private boolean describesNewTestSet( Description description )
90      {
91          if ( currentTestSetDescription != null )
92          {
93              if ( null != description.getTestClass() )
94              {
95                  return !description.getTestClass().equals( currentTestSetDescription.getTestClass() );
96              }
97              else if ( description.isSuite() )
98              {
99                  return description.getChildren().equals( currentTestSetDescription.getChildren() );
100             }
101 
102             return false;
103         }
104 
105         return true;
106     }
107 
108     @Override
109     public void testFinished( Description description )
110         throws Exception
111     {
112         super.testFinished( description );
113         this.lastFinishedDescription = description;
114     }
115 
116     @Override
117     public void testIgnored( Description description )
118         throws Exception
119     {
120         finishLastTestSetIfNecessary( description );
121 
122         super.testIgnored( description );
123         this.lastFinishedDescription = description;
124     }
125 
126     @Override
127     public void testFailure( Failure failure )
128         throws Exception
129     {
130         finishLastTestSetIfNecessary( failure.getDescription() );
131 
132         super.testFailure( failure );
133         this.lastFinishedDescription = failure.getDescription();
134     }
135 
136     @Override
137     public void testAssumptionFailure( Failure failure )
138     {
139         super.testAssumptionFailure( failure );
140         this.lastFinishedDescription = failure.getDescription();
141     }
142 
143     @Override
144     public void testRunStarted( Description description )
145         throws Exception
146     {
147     }
148 
149     @Override
150     public void testRunFinished( Result result )
151         throws Exception
152     {
153         if ( lastFinishedDescription != null )
154         {
155             reporter.testSetCompleted( createReportEntryForTestSet( lastFinishedDescription ) );
156             lastFinishedDescription = null;
157         }
158     }
159 }